/* unknown
* 未知类型的值，需要进行类型检查或类型断言才能使用， 不可以在任意值上访问属性,调用方法，且unknown类型的值不能直接赋值给其他变量
* */
//unknown
let unknownNever:unknown="冷月心"
unknownNever.getName();//报错
unknownNever.name//报错
// param是unknown类型，因为不知道 param 的类型，使用运算符 /，导致报错
function divide1(param: unknown) {
    return param / 2;
}
//1.类型断言解决
function divide2(param: unknown) {
    return param as number / 2;
}

// 2、类型守卫 —— 不飘红，且确保正常执行
function divide3(param: unknown) {
    if (typeof param === 'number') {
        // 推断出类型: number
        return param / 2;
    }
}

// 3、类型断言函数，抛出错误 —— 不飘红，且确保正常执行
function divide4(param: unknown) {
    assertIsNumber(param);
    return param / 2;
}
/** 类型断言函数，抛出错误 */
function assertIsNumber(arg: unknown): asserts arg is Number {
    if (!(arg instanceof Number)) {
        thrownewTypeError('Not a Number: ' + arg);
    }
}
//unknown类型的值也不能赋值给any和unknown以外的类型变量
let strVal: string
strVal = 'str'
strval = unknownNever// TS2322: Type 'unknown' is not assignable to type 'string'.

//在联合类型中,unknown吸收除any以外任何类型。即如果任一组成类型是unknown，联合类型也会相当于unknown
type unknownNever1 = unknown | null;       // unknown
type unknownNever2 = unknown | undefined;  // unknown
type unknownNever3 = unknown | string;     // unknown
type unknownNever4 = unknown | any;       // any

/*void
* 没有任何类型。
* */

const fn1 = (param:string): void => {
    console.log("我是没有返回值的函数");
};
//也可以用来声明变量,但只能作用在undefined。
const u:void=undefined;//用法很无语，基本不会这么用
const n:void=null;//这样会报错，只有tsconfig.json中strictNullChecks属性设置为false时,null才能赋值给void
const age:void=18;//这样也会报错

